package com.ncloud.crm.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.ncloud.crm.entity.Logistics;
import com.ncloud.crm.service.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ncloud.common.enmus.ResultEnum;
import com.ncloud.common.exception.UserException;
import com.ncloud.crm.common.Constant;
import com.ncloud.crm.entity.BsNode;
import com.ncloud.crm.entity.BsNodeAttr;
import com.ncloud.crm.entity.order.Work;
import com.ncloud.crm.entity.order.WorkAttr;
import com.ncloud.crm.entity.order.WorkNode;
import com.ncloud.crm.entity.order.WorkNodeAttr;
import com.ncloud.crm.entity.order.WorkNodeEqpt;
import com.ncloud.crm.entity.order.WorkNodeNetAccess;
import com.ncloud.crm.entity.order.WorkNodePublicCloud;
import com.ncloud.crm.mapper.WorkNodeMapper;
import com.ncloud.crm.utils.DateUtils;
import com.ncloud.crm.utils.OrderNodeDefineUtils;
import com.ncloud.crm.utils.TableIdDefineUtils;
import com.ncloud.param.service.SequenceService;

@Service
public class WorkNodeServiceImpl implements WorkNodeService {

	private static final Logger logger = LogManager.getLogger(WorkNodeServiceImpl.class);

	@Autowired
	private WorkNodeMapper workNodeMapper;
	@Autowired
	private BsNodeService bsNodeService;
	@Autowired
	private WorkNodeEqptService workNodeEqptService;
	@Autowired
	private WorkNodePublicCloudService workNodePublicCloudService;
	@Autowired
	private WorkNodeNetAccessService workNodeNetAccessService;
	@Autowired
	private WorkNodeAttrService workNodeAttrService;
	@Autowired
	private WorkAttrService WorkAttrService;
	@Reference
	private SequenceService sequenceService;
	@Autowired
	private BsNodeAttrService bsNodeAttrService;
	@Autowired
	private LogisticsServer logisticsServer;

	public JSONArray getId(JSONObject json) {
		if(json==null || !json.containsKey("workId")){
			throw new UserException(ResultEnum.PARAM_ERROR);
		}
		List<WorkNode> orderAttrs = workNodeMapper.getWorkNodeByWorkId(json.getLong("workId"));
		return JSON.parseArray(JSON.toJSONString(orderAttrs));
	}

	@Override
	public JSONObject getPk(JSONObject json) {
		return null;
	}

	@Override
	public JSONObject insert(JSONObject json) {

		WorkNode orderAttr = JSON.parseObject(json.toJSONString(),WorkNode.class);
		try {
			validation(orderAttr);
			workNodeMapper.insertWorkNode(orderAttr);
		}catch (RuntimeException e){
			e.printStackTrace();
			throw new UserException(ResultEnum.DATABASE_ERROR);
		}
		return json;
	}
	private void validation(WorkNode workNode){
		if(workNode.getNodeId() == null){
			Long id = sequenceService.getSequence("seq_node_id");
			workNode.setNodeId(id);
		}

	}

	@Override
	public List<WorkNode> getNodesByWorkId(Long workId) {
		return workNodeMapper.getWorkNodeByWorkId(workId);
	}

	@Override
	public JSONObject validate(JSONObject json,JSONObject result) {
		JSONObject jsonObject = new JSONObject();
		JSONArray nodeArray = new JSONArray();
		JSONArray nodeEqptArray = new JSONArray();
		JSONArray nodePublicCloudArray = new JSONArray();
		JSONArray nodeInterArray = new JSONArray();
		JSONArray workArray = new JSONArray();
		JSONArray nodeItemArray = new JSONArray();
		JSONArray cloudSegArray = new JSONArray();
		//JSONArray nodeAttrArray = new JSONArray();
		if(json == null){
			throw new UserException(ResultEnum.ORDER_INFO_ERROR);
		}

		//处理node节点
		if(json.containsKey(OrderNodeDefineUtils.NODE)){
			Date currentDate = new Date();
			JSONArray nodes = json.getJSONArray(OrderNodeDefineUtils.NODE);
			logger.info("前台组织的节点信息："+nodes.toJSONString());
			JSONObject relation = new JSONObject();
			if(result.containsKey(OrderNodeDefineUtils.DISCNT_NODE_RELATION)){
				relation =result.getJSONObject(OrderNodeDefineUtils.DISCNT_NODE_RELATION);
			}else {
				throw new UserException(ResultEnum.PARAM_ERROR.getCode(),"套餐和节点关系信息不存在！");
			}
			for(int j=0;j<nodes.size();j++){
				Work nodeWork = new Work();
				JSONObject node = nodes.getJSONObject(j);
				/*获取计费周期和单位*/
				int billingCycle = 0;
				String cycleUnit = "M";
				if(node.containsKey("cycleUnit") && node.containsKey("billingCycle")){
					billingCycle = node.getIntValue("billingCycle");
					cycleUnit = node.getString("cycleUnit");
				}else{
					throw new UserException(ResultEnum.PARAM_ERROR.getCode(),"节点计费周期和单位不存在{cycleUnit,billingCycle}");
				}
				/*约定序列*/
				String index = "";
				if(node.containsKey("index")){
					index = node.getString("index");
				}else{
					index = node.getString("discntId");
				}
				if(!relation.containsKey(index)){
					throw new UserException(ResultEnum.PARAM_ERROR.getCode(),"套餐和节点不能找到对应关系！{index}");
				}

				/*获取节点信息*/
				WorkNode obj = JSON.parseObject(node.toJSONString(),WorkNode.class);
				//WorkNode workNodeOld = JSON.parseObject(node.toJSONString(),WorkNode.class);
				String modifyTag = obj.getModifyTag();
						/*生成工单id*/
				Long workId = sequenceService.getSequence("seq_work_id");
				result.put(TableIdDefineUtils.WORK_ID,workId);
				obj.setWorkId(workId);
				//设置工单id
				nodeWork.setWorkId(workId);
				/*设置订单*/
				if(obj.getOrderId() == null){
					obj.setOrderId(result.getLong(TableIdDefineUtils.ORDER_ID));
				}

				/*处理custId*/
				if(obj.getCustId() == null){
					if(!result.containsKey(TableIdDefineUtils.CUST_ID) || StringUtils.isEmpty(result.getString(TableIdDefineUtils.CUST_ID))){
						if(modifyTag.equals(Constant.ADD)){
							throw new UserException(ResultEnum.PARAM_ERROR.getCode(),"当前节点的客户id不存在！");
						}
						throw new UserException(ResultEnum.ORDER_INFO_ERROR);
					}else{
						obj.setCustId(result.getLong(TableIdDefineUtils.CUST_ID));
					}
				}
				/*校验产品实例编码prod_inst_id*/
				if(obj.getProdInstId() == null) {
					if (!result.containsKey(TableIdDefineUtils.PROD_INST_ID) || StringUtils.isEmpty(result.getString(TableIdDefineUtils.PROD_INST_ID))) {
						throw new UserException(ResultEnum.PARAM_ERROR.getCode(), "当前节点的产品实例编码不存在{prodInstId}！");
					} else {
						obj.setProdInstId(result.getLong(TableIdDefineUtils.PROD_INST_ID));
					}
				}

				/*校验产品实例编码discnt_inst_id*/
				if(obj.getDiscntInstId() == null) {
					logger.info(obj.getDiscntId()+"=>"+index+"=>"+relation.getLong(index));
					obj.setDiscntInstId(relation.getLong(index));
				}
				/*新增节点处理*/
				if(Constant.ADD.equals(modifyTag)){
					/*生成节点ID*/
					Long id = sequenceService.getSequence("seq_node_id");
					obj.setNodeId(id);
					result.put(TableIdDefineUtils.NODE_ID,id);
					obj.setBeginDate(currentDate);
					/*计算结束时间*/
					obj.setEndDate(DateUtils.parseDate(Constant.END_DATE));
					obj.setUpdateTime(currentDate);
					obj.setUpdateUser(json.getLong("userUser"));

				}else if(Constant.UPDATE.equals(modifyTag)){//修改节点处理
							/*根据修改的节点查询对应的实例信息，对实例做旧单操作，对改单做新增操作*/
					if(obj.getNodeId() != null){
						BsNode bsNode =  bsNodeService.getNodeInfoByPk(obj.getNodeId());
						WorkNode workNodeOld = JSON.parseObject(JSON.toJSONString(bsNode),WorkNode.class);
						logger.debug("旧节点信息："+JSON.toJSONString(workNodeOld));
								/*旧记录*/
								/*当前时间减去1秒,实际结束时间应该以回单时间为准*/
						workNodeOld.setEndDate(currentDate);
						workNodeOld.setUpdateTime(currentDate);
						workNodeOld.setUpdateUser(json.getLong("userId"));
						workNodeOld.setWorkId(workId);
						workNodeOld.setModifyTag(Constant.DEL);
						workNodeOld.setOrderId(result.getLong(TableIdDefineUtils.ORDER_ID));
								/*新记录*/
							/*	Long id = sequenceService.getSequence("seq_node_id");
								obj.setNodeId(id);
								result.put("newNodeId",id);*/
						//obj.setWorkId(workId);
						obj.setBeginDate(currentDate);
						obj.setEndDate(DateUtils.parseDate(Constant.END_DATE));
						obj.setUpdateTime(currentDate);
						obj.setUpdateUser(json.getLong("userId"));
						obj.setModifyTag(Constant.ADD);

						result.put(TableIdDefineUtils.NODE_ID,obj.getNodeId());
						//保存节点
						nodeArray.add(JSON.parseObject(JSON.toJSONString(workNodeOld)));

					}else{
						throw new UserException(ResultEnum.PARAM_ERROR.getCode(),"当前节点nodeId不存在！");
					}

				}else if(Constant.DEL.equals(modifyTag)){
					/*当前节点设置为立即失效*/
					obj.setEndDate(currentDate);
					obj.setUpdateTime(currentDate);
					obj.setUpdateUser(json.getLong("userId"));
					result.put(TableIdDefineUtils.NODE_ID,obj.getNodeId());
				}else{
					obj.setUpdateTime(currentDate);
					obj.setUpdateUser(json.getLong("userId"));
					result.put(TableIdDefineUtils.NODE_ID,obj.getNodeId());
				}
				/*处理CPE设备信息*/
				result.put("createDate",DateUtils.getDateTime());
				workNodeEqptService.eqptCPE(node,result,nodeEqptArray);
				/*处理公有云设备信息*/
				JSONObject segInfo =workNodePublicCloudService.eqptPublicCloud(node,result,nodePublicCloudArray);
				if(segInfo.containsKey(OrderNodeDefineUtils.PUBLIC_CLOUD_SEG)){
					cloudSegArray.addAll(segInfo.getJSONArray(OrderNodeDefineUtils.PUBLIC_CLOUD_SEG));
				}
				/*isp信息处理*/
				workNodeNetAccessService.nodeNetAccess(node,result,nodeInterArray);
				/*处理节点属性信息*/
				workNodeAttrService.nodeItemInfos(node,result, nodeItemArray,"node_item_array");

				/*订单Id*/
				if(!result.containsKey(TableIdDefineUtils.ORDER_ID) || StringUtils.isEmpty(result.getString(TableIdDefineUtils.ORDER_ID))){
					throw new UserException(ResultEnum.PARAM_ERROR);
				}else{
					nodeWork.setOrderId(result.getLong(TableIdDefineUtils.ORDER_ID));
				}
						/*节点id*/
				if(obj.getNodeId() == null){
					if(!result.containsKey(TableIdDefineUtils.NODE_ID) || StringUtils.isEmpty(result.getString(TableIdDefineUtils.NODE_ID))){
						throw new UserException(ResultEnum.PARAM_ERROR);
					}else{
						nodeWork.setNodeId(result.getLong(TableIdDefineUtils.NODE_ID));
					}
				}else{
					nodeWork.setNodeId(obj.getNodeId());
				}
						/*设置订单*/
				nodeWork.setOrderId(result.getLong(TableIdDefineUtils.ORDER_ID));
						/*施工环节，默认1*/
				nodeWork.setConstructItem("1");
						/*这里先写死*/
						/*施工人*/
				//nodeWork.setConstructUser(1L);
						/*施工时间*/
				//nodeWork.setConstructTime(new Date());
				/*创建时间*/
				nodeWork.setCreateTime(currentDate);
				nodeWork.setWorkState(Constant.WORK_STATE_INIT);
				workArray.add(JSON.parseObject(JSON.toJSONString(nodeWork)));
				//保存新节点节点
				nodeArray.add(JSON.parseObject(JSON.toJSONString(obj)));


			}
			//节点信息
			jsonObject.put(OrderNodeDefineUtils.NODE,nodeArray);
			//组装cpe设备
			jsonObject.put(OrderNodeDefineUtils.NODE_EQPT,nodeEqptArray);
			//组装公有云设备
			jsonObject.put(OrderNodeDefineUtils.NODE_PUBLIC_CLOUD,nodePublicCloudArray);
			//组装isp
			jsonObject.put(OrderNodeDefineUtils.NODE_INTER,nodeInterArray);
			//组装work
			jsonObject.put(OrderNodeDefineUtils.WORK,workArray);
			//组装属性节点信息
			jsonObject.put(OrderNodeDefineUtils.NODE_ITEM,nodeItemArray);
			//组装云网段信息
			jsonObject.put(OrderNodeDefineUtils.PUBLIC_CLOUD_SEG,cloudSegArray);
			//合同节点关系信息
			//jsonObject.put(OrderNodeDefineUtils.CONTRACT_NODE,contractNodeArray);

		}
		return jsonObject;
	}

	@Override
	public int updateWorkNode(WorkNode workNode) {
		return workNodeMapper.updateWorkNode(workNode);
	}

	@Override
	public JSONObject getNewNodeInfo(WorkNode workNode) {
		Long workId = workNode.getWorkId();
		Long nodeId = workNode.getNodeId();
		//获取节点属性信息
		List<BsNodeAttr> nodeAttrs = bsNodeAttrService.getNodeAttrs(workNode.getNodeId());
		//获取节点属性
		List<WorkNodeAttr> workNodeAttrs = workNodeAttrService.getNodeAttrsByWorkId(workId);
		workNodeAttrs.removeIf(x->!Constant.ADD.equals(x.getModifyTag()));
		
		//获取节点接入信息
		List<WorkNodeNetAccess> nodeNetAccesses = workNodeNetAccessService.getNewNodeIntersByWorkId(workId,nodeId);
		List<WorkNodeNetAccess> wan = new ArrayList<WorkNodeNetAccess>();
		List<WorkNodeNetAccess> lan = new ArrayList<WorkNodeNetAccess>();
		nodeNetAccesses.forEach(x -> {if("1".equals(x.getNetType())) lan.add(x); else wan.add(x);});
		JSONObject isp = new JSONObject();
		if(wan.size()>0)
			isp.put("wan", JSON.parseObject(JSON.toJSONString(wan.get(0),SerializerFeature.WriteMapNullValue)));
		else {
			isp.put("wan",new JSONObject());
		}
		if(lan.size()>0){
			isp.put("lan", JSON.parseObject(JSON.toJSONString(lan.get(0),SerializerFeature.WriteMapNullValue)));
		}else {
			isp.put("lan",new JSONObject());
		}
		
		//获取节点设备信息
		List<WorkNodeEqpt> nodeEqpts = workNodeEqptService.getNewNodeEqptsByWorkId(workId,nodeId);
		
		JSONObject workNodePublicCloud = workNodePublicCloudService.getNewListByWorkId(workId,nodeId);
		
		//获取施工单属性
		List<WorkAttr> workAttrs = WorkAttrService.getAttrsByWorkId(workId);

		//获取物流信息
		Logistics logistics = logisticsServer.getLogisticsInfoByNode(workId,nodeId);
		//组织输出参数
		JSONObject nodeJson = new JSONObject();
		if(nodeJson!=null) nodeJson = JSON.parseObject(JSON.toJSONString(workNode,SerializerFeature.WriteMapNullValue));
		JSONArray nodeAttrArray = JSON.parseArray(JSON.toJSONString(nodeAttrs,SerializerFeature.WriteMapNullValue));
		JSONArray workNodeAttrArray = JSON.parseArray(JSON.toJSONString(workNodeAttrs,SerializerFeature.WriteMapNullValue));
		JSONArray workAttrArray = JSON.parseArray(JSON.toJSONString(workAttrs,SerializerFeature.WriteMapNullValue));
		setAttr2Object(nodeAttrArray,nodeJson);
		setAttr2Object(workNodeAttrArray, nodeJson);
		setAttr2Object(workAttrArray, nodeJson);
		nodeJson.put("isp", isp);
//		nodeJson.put("nodeEqpt", JSON.parseArray(JSON.toJSONString(nodeEqpts)));
		if(nodeEqpts.size()>0)
			nodeJson.put("nodeEqpt",JSON.parseObject(JSON.toJSONString(nodeEqpts.get(0),SerializerFeature.WriteMapNullValue),Feature.IgnoreNotMatch));
		else nodeJson.put("nodeEqpt",new JSONObject());
		nodeJson.put("pubCloud",workNodePublicCloud);
		nodeJson.put("postInfo",JSON.parseObject(JSON.toJSONString(logistics)));
		return nodeJson;
	}
	
	private void setAttr2Object(JSONArray nodeAttrArray, JSONObject nodeJson) {
		for(int i=0;i<nodeAttrArray.size();i++){
			JSONObject attr = nodeAttrArray.getJSONObject(i);
			String key = attr.getString("attrCode");
			nodeJson.put(key,attr.getString("attrValue"));
		}
	}

	@Override
	public JSONObject getNodeChangeOldInfo(WorkNode workNode) {
		Long workId = workNode.getWorkId();
		
		//获取节点属性
		List<WorkNodeAttr> workNodeAttrs = workNodeAttrService.getNodeAttrsByWorkId(workId);
		workNodeAttrs.removeIf(x->!Constant.DEL.equals(x.getModifyTag()));
		
		//获取节点接入信息
		List<WorkNodeNetAccess> nodeNetAccesses = workNodeNetAccessService.getNodeIntersByWorkId(workId);
		nodeNetAccesses.removeIf(x->!Constant.DEL.equals(x.getModifyTag()));
		
		List<WorkNodeNetAccess> wan = new ArrayList<WorkNodeNetAccess>();
		List<WorkNodeNetAccess> lan = new ArrayList<WorkNodeNetAccess>();
		nodeNetAccesses.forEach(x -> {if("1".equals(x.getNetType())) lan.add(x); else wan.add(x);});
		JSONObject isp = new JSONObject();
		if(wan.size()>0)
			isp.put("wan", JSON.parseObject(JSON.toJSONString(wan.get(0),SerializerFeature.WriteMapNullValue)));
		else {
			isp.put("wan",new JSONObject());
		}
		if(lan.size()>0){
			isp.put("lan", JSON.parseObject(JSON.toJSONString(lan.get(0),SerializerFeature.WriteMapNullValue)));
		}else {
			isp.put("lan",new JSONObject());
		}

		//获取节点设备信息
		List<WorkNodeEqpt> nodeEqpts = workNodeEqptService.getNodeEqptsByWorkId(workId);
		nodeEqpts.removeIf(x->!Constant.DEL.equals(x.getModifyTag()));
		
		//公有云信息（变更暂时不考虑，网段信息未处理）
		List<WorkNodePublicCloud> workNodePublicClouds = workNodePublicCloudService.getListByWorkId(workId);
		workNodePublicClouds.removeIf(x->!Constant.DEL.equals(x.getModifyTag()));
		
		//组织输出参数
		JSONObject nodeJson = new JSONObject();
		if(nodeJson!=null) nodeJson = JSON.parseObject(JSON.toJSONString(workNode,SerializerFeature.WriteMapNullValue));
		JSONArray workNodeAttrArray = JSON.parseArray(JSON.toJSONString(workNodeAttrs,SerializerFeature.WriteMapNullValue));
		setAttr2Object(workNodeAttrArray, nodeJson);
		nodeJson.put("nodeNetAccess", isp);
//		nodeJson.put("nodeEqpt", JSON.parseArray(JSON.toJSONString(nodeEqpts)));
		if(nodeEqpts.size()>0)
			nodeJson.put("nodeEqpt",JSON.parseObject(JSON.toJSONString(nodeEqpts.get(0),SerializerFeature.WriteMapNullValue),Feature.IgnoreNotMatch));
		else nodeJson.put("nodeEqpt",new JSONObject());
		if(workNodePublicClouds.size()>0)
			nodeJson.put("pubCloud",JSON.parseObject(JSON.toJSONString(workNodePublicClouds.get(0),SerializerFeature.WriteMapNullValue),Feature.IgnoreNotMatch));
		else {
			nodeJson.put("pubCloud",new JSONObject());
		}
		return nodeJson;
	}

	@Override
	public List<WorkNode> getNodesByOrderId(Long orderId) {
		return workNodeMapper.getNodesByOrderId(orderId);
	}


}
